package com.zytlifeservice.service.pay;

import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.demo.trade.config.Configs;
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.alipay.demo.trade.model.builder.AlipayTradeQueryRequestBuilder;
import com.alipay.demo.trade.model.builder.AlipayTradeRefundRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.model.result.AlipayF2FQueryResult;
import com.alipay.demo.trade.model.result.AlipayF2FRefundResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl;
import com.google.gson.Gson;
import com.zytlifeservice.domain.pay.AlipayOrder;
import com.zytlifeservice.repository.pay.AlipayOrderRepository;
import com.zytlifeservice.response.SuccessResponse;
import com.zytlifeservice.util.TextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * Created by MJS on 2017/5/22.
 */

@Service
public class AlipayService {

    private static final Logger log = LoggerFactory.getLogger(AlipayService.class);


    @Value("${alipay_callback}")
    private String callBackUrl;

    @Autowired
    private AlipayOrderRepository alipayOrderRepository;

    // 支付宝当面付2.0服务
    private static AlipayTradeService tradeService;

    static {
        Configs.init("zfbinfo.properties");

        /** 使用Configs提供的默认参数
         *  AlipayTradeService可以使用单例或者为静态成员对象，不需要反复new
         */
        tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();
    }

    public String pay(AlipayOrder alipayOrder) {
        log.error("callbackUrl={}", callBackUrl);
        String res = "error";
        String subject = alipayOrder.getSubject();

//        String totalAmount = "0.01";
        String totalAmount = alipayOrder.getTotalAmount();

        String storeId = alipayOrder.getStoreId();

        String timeoutExpress = "5m";

        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                .setSubject(subject).setTotalAmount(totalAmount).setOutTradeNo(alipayOrder.getOutTradeNo())
                .setStoreId(storeId)
                .setTimeoutExpress(timeoutExpress)
                .setNotifyUrl(callBackUrl);

        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                log.info("支付宝预下单成功: )");
                AlipayTradePrecreateResponse response = result.getResponse();
                alipayOrder.setOrderStatus(AlipayOrder.ORDER_WAIT);
                if (response != null && "10000".equals(response.getCode())) {
                    res = getQrCode(response.getBody());
                }
                break;

            case FAILED:
                log.error("支付宝预下单失败!!!");
                alipayOrder.setOrderStatus(AlipayOrder.ORDER_FAIL);
                res = "error";
                break;

            case UNKNOWN:
                log.error("系统异常，预下单状态未知!!!");
                alipayOrder.setOrderStatus(AlipayOrder.ORDER_EXCEPTION);
                res = "exception";
                break;

            default:
                log.error("不支持的交易状态，交易返回异常!!!");
                alipayOrder.setOrderStatus(AlipayOrder.ORDER_EXCEPTION);
                res = "exception";
                break;
        }
        alipayOrderRepository.save(alipayOrder);
        return res;
    }


    private String getQrCode(String body) {
        Gson gson = new Gson();
        SuccessResponse successResponse = gson.fromJson(body, SuccessResponse.class);
        log.info(successResponse.toString());
        if (successResponse.getAlipay_trade_precreate_response().getCode().equalsIgnoreCase("10000")) {
            return successResponse.getAlipay_trade_precreate_response().getQr_code();
        } else return "error";
    }

    public String reFund(AlipayOrder alipayOrder) {
        return reFund(alipayOrder, "");
    }

    public String reFund(AlipayOrder alipayOrder, String refund_free) {
        String res = "";
        String outTradeNo = alipayOrder.getOutTradeNo();
        // (必填) 退款金额，该金额必须小于等于订单的支付金额，单位为元
        String refundAmount = TextUtil.isEmpty(refund_free) ? alipayOrder.getTotalAmount() : refund_free;
        // (可选，需要支持重复退货时必填) 商户退款请求号，相同支付宝交易号下的不同退款请求号对应同一笔交易的不同退款申请，
        // 对于相同支付宝交易号下多笔相同商户退款请求号的退款交易，支付宝只会进行一次退款
        String outRequestNo = "zytrefund" + System.currentTimeMillis()   //添加userId
                + (long) (Math.random() * 10000000L);

        // (必填) 退款原因，可以说明用户退款原因，方便为商家后台提供统计
        String refundReason = alipayOrder.getRefundReason();  //一般情况代表无货。
        // (必填) 商户门店编号，退款情况下可以为商家后台提供退款权限判定和统计等作用，详询支付宝技术支持
        String storeId = alipayOrder.getStoreId();
        AlipayTradeRefundRequestBuilder builder = new AlipayTradeRefundRequestBuilder()
                .setOutTradeNo(outTradeNo).setRefundAmount(refundAmount).setRefundReason(refundReason)
                .setOutRequestNo(outRequestNo).setStoreId(storeId);
        AlipayF2FRefundResult result = tradeService.tradeRefund(builder);
        log.error("alipay refund res ={}", result);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                log.info("支付宝退款成功: )");
                res = "支付宝退款成功: )";
                alipayOrder.setRefundStatus(0);
                break;

            case FAILED:
                log.error("支付宝退款失败!!!");
                res = "支付宝退款失败!!!";
                alipayOrder.setRefundStatus(-1);
                break;

            case UNKNOWN:
                log.error("系统异常，订单退款状态未知!!!");
                res = "系统异常，订单退款状态未知!!!";
                alipayOrder.setRefundStatus(-1);
                break;

            default:
                log.error("不支持的交易状态，交易返回异常!!!");
                res = "不支持的交易状态，交易返回异常!!!";
                alipayOrder.setRefundStatus(-1);
                break;
        }
        alipayOrderRepository.save(alipayOrder);
        return res;
    }


    public Object query(String outTradeNo) {
        AlipayF2FQueryResult result = tradeService.queryTradeResult(new AlipayTradeQueryRequestBuilder().setOutTradeNo(outTradeNo));
        return result;
    }
}
